home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xinu.arc / XINU2.C < prev    next >
Text File  |  1986-01-03  |  30KB  |  1,115 lines

  1. /* conf.c  p. 152 */
  2.  
  3. # include    <conf.h>
  4.  
  5. /* device independent I/O switch */
  6.  
  7. struct devsw    devtab[NDEVS] = {
  8.     
  9.     /*  Format of entries is:
  10.     major-device-numberè    init, open, close,
  11.     read, write, seek,
  12.     getc, putc, cntl,
  13.     device-csr-address, input-vector, output-vector,
  14.     iint-handler, oint-handler, control-block, minor-device-number,
  15.     */
  16.     
  17.     /*  CONSOLE  */
  18.     0,
  19.     ttyinit,    ionull,        ionull,
  20.     ttyread,    ttywrite,    ioerr,
  21.     ttygetc,    ttyputc,    ttycntl,
  22.     0177560,    0060,        0064,
  23.     ttyiin,        ttyoin,        NULLPTR,    0,
  24.     
  25.     /*  OTHER  */
  26.     1,
  27.     ttyinit,    ionull,        ionull,
  28.     ttyread,    ttywrite,    ioerr,
  29.     ttygetc,    ttyputc,    ttycntl,
  30.     0176500,    0300,        0304,
  31.     ttyiin,        ttyoin,        NULLPTR,    1,
  32.     
  33.     /*  DISD0  */
  34.     2,
  35.     dsinit,        dsopen,        ioerr,
  36.     dsread,        dswrite,    dsseek,
  37.     ioerr,        ioerr,        dscntl,
  38.     0177460,    0134,        0134,
  39.     dsinter,    dsinter,    NULLPTR,    0,
  40.     
  41.     /*  FILE1  */
  42.     3,
  43.     lfinit,        ioerr,        lfclose,
  44.     lfread,        lfwrite,    lfseek,
  45.     lfgetc,        lfputc,        ioerr,
  46.     0000000,    0000,        0000,
  47.     ioerr,        ioerr,        NULLPTR,    0,
  48.     
  49.     /*  FILE2  */
  50.     4,
  51.     lfinit,        ioerr,        lfclose,
  52.     lfread,        lfwrite,    lfseek,
  53.     lfgetc,        lfputc,        ioerr,
  54.     0000000,    0000,        0000,
  55.     ioerr,        ioerr,        NULLPTR,    1,
  56.     
  57.     /*  FILE3  */
  58.     5,
  59.     lfinit,        ioerr,        lfclose,
  60.     lfread,        lfwrite,    lfseek,
  61.     lfgetc,        lfputc,        ioerr,
  62.     0000000,    0000,        0000,
  63.     ioerr,        ioerr,        NULLPTR,    2,
  64.     è    /*  FILE4  */
  65.     6,
  66.     lfinit,        ioerr,        lfclose,
  67.     lfread,        lfwrite,    lfseek,
  68.     lfgetc,        lfputc,        ioerr,
  69.     0000000,    0000,        0000,
  70.     ioerr,        ioerr,        NULLPTR,    3,
  71.  
  72.     /* MEMORY */
  73.     7,
  74.     ionull,         ionull,         ioerr,
  75.     memread,        memwrite,       ionull,
  76.         ioerr,          ioerr,          ionull,
  77.         0000000,        0000,           0000,
  78.     ioerr,          ioerr,          NULLPTR,       0
  79.         
  80. };
  81. /* dfckmd.c - dfckmd  p. 322 */
  82.  
  83. #include    <conf.h>
  84. #include    <kernel.h>
  85. #include    <disk.h>
  86. #include    <file.h>
  87.  
  88. /*-----------------------------------------------------------------------------
  89.  *  dfckmd  --  parse file mode argument and generate actual mode bits
  90.  *-----------------------------------------------------------------------------
  91.  */
  92.  
  93. dfckmd(mode)
  94.     char    *mode;
  95. {
  96.     int    mbits;
  97.     char    ch;
  98.  
  99.     mbits = 0;
  100.     while (ch = *mode++)
  101.         switch(ch)  {
  102.  
  103.             case 'r':    if (mbits&FLREAD) return(SYSERR);
  104.                     mbits |= FLREAD;
  105.                     break;
  106.  
  107.             case 'w':    if (mbits&FLWRITE) return(SYSERR);
  108.                     mbits |= FLWRITE;
  109.                     break;
  110.  
  111.             case 'o':    if (mbits&FLOLD || mbits&FLNEW)
  112.                         return(SYSERR);
  113.                     mbits |= FLOLD;
  114.                     break;
  115.  
  116.             case 'n':    if (mbits&FLOLD || mbits&FLNEW)
  117.                         return(SYSERR);
  118.                     mbits |= FLNEW;
  119.                     break;
  120.  
  121.             default:    return(SYSERR);
  122.         }
  123.     if ((mbits&FLREAD) == (mbits&FLWRITE))    /* default: allow r + w      */
  124.         mbits |= (FLREAD|FLWRITE);
  125.     return(mbits);
  126. }
  127. /* dsinter.c - dsinter  p. 298 */
  128.  
  129. # include    <conf.h>
  130. # include    <kernel.h>
  131. # include    <disk.h>
  132.  
  133. /*-----------------------------------------------------------------------------
  134.  *  dsinter  --  process a disk interrupt ( DTC interface; XEBEC controller )
  135.  *-----------------------------------------------------------------------------
  136.  */
  137. INTPROC    dsinter(dsptr)
  138.     struct dsblk    *dsptr;
  139. {
  140.     struct dtc    *dtptr;
  141.     struct dreq    *drptr;
  142.  
  143.     dtptr = dsptr->dcsr;
  144.     drptr = dsptr->dreqlst;
  145.     if (drptr == DRNULL)  {
  146.         panic("disk interrupt when disk not busy");
  147.         return;
  148.     }
  149.     if (dtptr->dt_csr & DTERROR)
  150.         drptr->drstat = SYSERR;
  151.     else
  152.         drptr->drstat = OK;
  153.     if ((dsptr->dreqlst=drptr->drnext) != DRNULL)
  154.         dskstrt(dsptr);
  155.     switch(drptr->drop)  {
  156.  
  157.         case DREAD:
  158.         case DSYNC:
  159.             ready(drptr->drpid,RESCHYES);
  160.             return;
  161.  
  162.         case DWRITE:
  163.             freebuf(drptr->drbuff);
  164.         case DSEEK:
  165.             freebuf(drptr);
  166.     }
  167. }
  168. /* dsopen.c - dsopen  p. 326 */
  169.  
  170. # include    <conf.h>
  171. # include    <kernel.h>
  172. # include    <disk.h>
  173. # include    <file.h>
  174. # include    <dir.h>
  175.  
  176. /*-----------------------------------------------------------------------------
  177.  *  dsopen  --  open/create a file on the specified disk device
  178.  *-----------------------------------------------------------------------------
  179.  */
  180. dsopen(devptr, filenam, mode)
  181.     struct devsw    *devptr;
  182.     char    *filenam;
  183.     char    *mode;
  184. {
  185.     struct dir    *dirptr;
  186.     struct flblk    *flptr;
  187.     struct fdes    *fdptr;
  188.     DBADDR    dba;
  189.     int    mbits, findex;
  190.     int    retcode;
  191.     char    ps;
  192.  
  193.     disable(ps);
  194.     dirptr = dsdirec(devptr->dvnum);
  195.     if ((mbits=dfckmd(mode)) == SYSERR)
  196.         retcode = SYSERR;
  197.     else if ((fdptr=dfdsrch(devptr->dvioblk,filenam,mbits))
  198.             == (struct fdes *)SYSERR)
  199.         retcode = SYSERR;
  200.     else if ((findex=dfalloc()) == SYSERR)
  201.         retcode = SYSERR;
  202.     else  {
  203.         flptr = &fltab[findex];
  204.         flptr->fl_dev = devptr->dvnum;
  205.         flptr->fl_dent = fdptr;
  206.         flptr->fl_mode = mbits & FLRW;
  207.         flptr->fl_iba = fdptr->fdiba;
  208.         ibget(flptr->fl_dev,flptr->fl_iba,&(flptr->fl_iblk));
  209.         flptr->fl_pos = 0L;
  210.         flptr->fl_dch = FALSE;
  211.         dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum = 0];
  212.         if (dba != DBNULL)  {
  213.             read(flptr->fl_dev, flptr->fl_buff, dba);
  214.             flptr->fl_bptr = flptr->fl_buff;
  215.         }  else
  216.             flptr->fl_bptr = &flptr->fl_buff[DBUFSIZ];
  217.         retcode = flptr->fl_id;
  218.     }
  219.     restore(ps);
  220.     return(retcode);
  221. }
  222. /* freebuf.c - freebuf  p. 237 */
  223.  
  224. # include    <conf.h>
  225. # include    <kernel.h>
  226. # include    <mark.h>
  227. # include    <bufpool.h>
  228.  
  229. /*-----------------------------------------------------------------------------
  230.  *  freebuf  --  free a buffer that was allocated from a pool by getbuf
  231.  *-----------------------------------------------------------------------------
  232.  */
  233. freebuf(buf)
  234.     int    *buf;
  235. {
  236.     char    ps;
  237.     int    poolid;
  238.  
  239. # ifdef    MEMMARK
  240.     if (unmarked(bpmark))
  241.         return(SYSERR);
  242. # endif
  243.     poolid = *(--buf);
  244.     if (poolid<0 || poolid>=nbpools)
  245.         return(SYSERR);
  246.     disable(ps);
  247.     *buf = bptab[poolid].bpnext;
  248.     bptab[poolid].bpnext = buf;
  249.     restore(ps);
  250.     signal(bptab[poolid].bpsem);
  251.     return(OK);
  252. }
  253. /* getitem.c - getfirst, getlast  p. 48 */
  254.  
  255. # include    <conf.h>
  256. # include    <kernel.h>
  257. # include    <q.h>
  258.  
  259. /*-----------------------------------------------------------------------------
  260.  * getfirst  --  remove and return the first process on a list
  261.  *-----------------------------------------------------------------------------
  262.  */
  263. int    getfirst(head)
  264.     int    head;            /* q index of head of list           */
  265. {
  266.     int    proc;            /* first process on the list         */
  267.  
  268.     if ((proc=q[head].qnext) < NPROC)
  269.         return( dequeue(proc) );
  270.     else
  271.         return(EMPTY);
  272. }
  273.  
  274.  
  275. /*-----------------------------------------------------------------------------
  276.  * getlast  --  remove and return the last process from a list
  277.  *-----------------------------------------------------------------------------
  278.  */
  279. int    getlast(tail)
  280.     int    tail;            /* q index of tail of list           */
  281. {
  282.     int    proc;            /* last process on the list          */
  283.  
  284.     if ((proc=q[tail].qprev) < NPROC)
  285.         return( dequeue(proc) );
  286.     else
  287.         return(EMPTY);
  288. }
  289. /* ibclear.c - ibclear  p. 311 */
  290.  
  291. # include    <conf.h>
  292. # include    <kernel.h>
  293. # include    <disk.h>
  294. # include    <file.h>
  295. # include    <dir.h>
  296.  
  297. /*-----------------------------------------------------------------------------
  298.  *  ibclear  --  clear in-core copy of an iblock
  299.  *-----------------------------------------------------------------------------
  300.  */
  301. ibclear(ibptr, ibbyte)
  302.     struct iblk    *ibptr;
  303.     long    ibbyte;
  304. {
  305.     int    i;
  306.  
  307.     ibptr->ib_byte = ibbyte;
  308.     for (i=0 ; i<IBLEN ; i++)
  309.         ibptr->ib_dba[i] = DBNULL;
  310.     ibptr->ib_next = IBNULL;
  311. }
  312. /* ibput.c - ibput  p. 313 */
  313.  
  314. # include    <conf.h>
  315. # include    <kernel.h>
  316. # include    <io.h>
  317. # include    <disk.h>
  318. # include    <file.h>
  319. # include    <dir.h>
  320.  
  321. /*-----------------------------------------------------------------------------
  322.  *  ibput  --  write an iblock back to disk given its number
  323.  *-----------------------------------------------------------------------------
  324.  */
  325. ibput(diskdev, inum, loc)
  326.     int    diskdev;
  327.     IBADDR    inum;
  328.     struct iblk    *loc;
  329. {
  330.     DBADDR    dba;    
  331.     char    *buff;
  332.     char    *to, *from;
  333.     int    i;
  334.     int    ibsem;
  335.  
  336.     dba = ibtodb(inum);
  337.     buff = getbuf(dskdbp);
  338.     ibsem = ((struct dsblk *)devtab[diskdev].dvioblk)->dibsem;
  339.     wait(ibsem);
  340.     read(diskdev, buff, dba);
  341.     to = buff + ibdisp(inum);
  342.     from = (char *)loc;
  343.     for (i=0 ; i<sizeof(struct iblk) ; i++)
  344.         *to++ = *from++;
  345.     write(diskdev, buff, dba);
  346.     signal(ibsem);
  347.     return(OK);    
  348. }
  349. /* insertd.c - insertd  p. 127 */
  350.  
  351. # include    <conf.h>
  352. # include    <kernel.h>
  353. # include    <q.h>
  354.  
  355. /*-----------------------------------------------------------------------------
  356.  *  insertd  --  insert process pid in delta list "head", given by its key
  357.  *-----------------------------------------------------------------------------
  358.  */
  359. insertd(pid, head, key)
  360.     int    pid;
  361.     int    head;
  362.     int    key;
  363. {
  364.     int    next;            /* runs through list                 */
  365.     int    prev;            /* followes next through list        */
  366.  
  367.     for (prev=head,next=q[head].qnext ;
  368.          q[next].qkey < key ; prev=next,next=q[next].qnext)
  369.         key -= q[next].qkey;
  370.     q[pid].qnext = next;
  371.     q[pid].qprev = prev;
  372.     q[pid].qkey  = key;
  373.     q[prev].qnext = pid;
  374.     q[next].qprev = pid;
  375.     if (next < NPROC)
  376.         q[next].qkey -= key;
  377.     return(OK);
  378. }
  379. /* kill.c - kill  p. 71 */
  380.  
  381. # include    <conf.h>
  382. # include    <kernel.h>
  383. # include    <proc.h>
  384. # include    <sem.h>
  385. # include    <mem.h>
  386.  
  387. /*-----------------------------------------------------------------------------
  388.  * kill  --  kill a process and remove it from the system
  389.  *-----------------------------------------------------------------------------
  390.  */
  391. SYSCALL    kill(pid)
  392.     int    pid;            /* process to kill                   */
  393. {
  394.     struct pentry    *pptr;        /* points to process table for pid   */
  395.     char    ps;            /* saved processor status            */
  396.  
  397.     disable(ps);
  398.     if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE)  {
  399.         restore(ps);
  400.         return(SYSERR);
  401.     }
  402.     if (--numproc == 0)
  403.         xdone();
  404.     freestk(pptr->pbase, pptr->pstklen);
  405.     switch (pptr->pstate)  {
  406.  
  407.         case PRCURR:    pptr->pstate = PRFREE;    /* suicide */
  408.                 resched();
  409.  
  410.         case PRWAIT:    semaph[pptr->psem].semcnt++;
  411.  
  412.         case PRSLEEP:
  413.         case PRREADY:    dequeue(pid);
  414.  
  415.         default:    pptr->pstate = PRFREE;
  416.     }
  417.     restore(ps);
  418.     return(OK);
  419. }
  420. /* lfinit.c - lfinit  p. 340 */
  421.  
  422. # include    <conf.h>
  423. # include    <kernel.h>
  424. # include    <disk.h>
  425. # include    <file.h>
  426.  
  427. # ifdef    Ndf
  428. struct flblk    fltab[Ndf];
  429. # endif
  430.  
  431. /*-----------------------------------------------------------------------------
  432.  *  lfinit  --  mark disk file 'device' available at system startup
  433.  *-----------------------------------------------------------------------------
  434.  */
  435. lfinit(devptr)
  436.     struct devsw    *devptr;
  437. {
  438.     struct flblk    *flptr;
  439.  
  440.     devptr->dvioblk = flptr = &fltab[devptr->dvminor];
  441.     flptr->fl_pid = 0;
  442.     flptr->fl_id = devptr->dvnum;
  443.     return(OK);
  444. }
  445. /* lfseek.c - lfseek  p. 332 */
  446.  
  447. # include    <conf.h>
  448. # include    <kernel.h>
  449. # include    <disk.h>
  450. # include    <file.h>
  451. # include    <dir.h>
  452.  
  453. /*-----------------------------------------------------------------------------
  454.  *  lfseek  --  seek to a specified position of a file
  455.  *-----------------------------------------------------------------------------
  456.  */
  457. lfseek(devptr, offset)
  458.     struct devsw    *devptr;
  459.     long    offset;
  460. {
  461.     struct flblk    *flptr;
  462.     int    retcode;
  463.     char    ps;
  464.  
  465.     disable(ps);
  466.     flptr = (struct flblk *)devptr->dvioblk;
  467.     if (flptr->fl_mode & FLWRITE)  {
  468.         if (flptr->fl_dch)
  469.             lfsflush(flptr);
  470.     } else if (offset > (flptr->fl_dent)->fdlen)  {
  471.             restore(ps);
  472.             return(SYSERR);
  473.     }
  474.     flptr->fl_pos = offset;
  475.     retcode = lfsetup(flptr->fl_dev, flptr);
  476.     restore(ps);
  477.     return(retcode);
  478. }
  479. /* lfwrite.c - lfwrite  p. 338 */
  480.  
  481. # include    <conf.h>
  482. # include    <kernel.h>
  483.  
  484. /*-----------------------------------------------------------------------------
  485.  *  lfwrite  --  write 'count' bytes onto a local disk file
  486.  *-----------------------------------------------------------------------------
  487.  */
  488. lfwrite(devptr, buff, count)
  489.     struct devsw    *devptr;
  490.     char    *buff;
  491.     int    count;
  492. {
  493.     int    i;
  494.  
  495.     if (count < 0)
  496.         return(SYSERR);
  497.     for (i=count ; i>0 ; i--)
  498.         if (lfputc(devptr, *buff++) == SYSERR)
  499.             return(SYSERR);
  500.     return(count);
  501. }
  502. /* lfputc.c - lfputc  p. 336 */
  503.  
  504. # include    <conf.h>
  505. # include    <kernel.h>
  506. # include    <proc.h>
  507. # include    <disk.h>
  508. # include    <file.h>
  509. # include    <dir.h>
  510.  
  511. /*-----------------------------------------------------------------------------
  512.  *  lfputc  --  put a character onto a (buffered) disk file
  513.  *-----------------------------------------------------------------------------
  514.  */
  515. lfputc(devptr, ch)
  516.     struct devsw    *devptr;
  517.     char    ch;
  518. {
  519.     struct flblk    *flptr;
  520.     char    ps;
  521.  
  522.     disable(ps);
  523.     flptr = (struct flblk *)devptr->dvioblk;
  524.     if (flptr->fl_pid!=currpid || !(flptr->fl_mode&FLWRITE))  {
  525.         restore(ps);
  526.         return(SYSERR);
  527.     }
  528.     if (flptr->fl_bptr >= &flptr->fl_buff[DBUFSIZ])  {
  529.         if (flptr->fl_dch)
  530.             lfsflush(flptr);
  531.         lfsetup(flptr->fl_dev, flptr);
  532.     }
  533.     if (flptr->fl_pos >= (flptr->fl_dent)->fdlen)
  534.         (flptr->fl_dent)->fdlen++;
  535.     flptr->fl_pos++;
  536.     *(flptr->fl_bptr)++ = ch;
  537.     flptr->fl_dch = TRUE;
  538.     restore(ps);
  539.     return(OK);
  540. }
  541. /* lfsetup.c - lfsetup  p. 331 */
  542.  
  543. # include    <conf.h>
  544. # include    <kernel.h>
  545. # include    <disk.h>
  546. # include    <file.h>
  547. # include    <dir.h>
  548.  
  549. /*-----------------------------------------------------------------------------
  550.  *  lfsetup  --  set up appropriate iblock and data block in memory
  551.  *-----------------------------------------------------------------------------
  552.  */
  553. lfsetup(diskdev, flptr)
  554.     int    diskdev;
  555.     struct flblk    *flptr;
  556. {
  557.     struct iblk    *ibptr;
  558.     int    displ, i;
  559.     long    ibrange;
  560.     IBADDR    nextib;
  561.     DBADDR    dba;
  562.  
  563.     ibrange = (long)(IBLEN * DBUFSIZ);
  564.     ibptr = &flptr->fl_iblk;
  565.     if (flptr->fl_pos < ibptr->ib_byte)  {
  566.         flptr->fl_iba = (flptr->fl_dent)->fdiba;
  567.         ibget(diskdev, flptr->fl_iba, ibptr);
  568.     }
  569.     while (ibptr->ib_byte+ibrange <= flptr->fl_pos)  {
  570.         if (ibptr->ib_next == IBNULL)  {
  571.             ibptr->ib_next = ibnew(diskdev, IBWDIR);
  572.             ibput(diskdev, flptr->fl_iba, ibptr);
  573.             flptr->fl_iba = ibptr->ib_next;
  574.             ibclear(ibptr, (long)ibptr->ib_byte+ibrange);
  575.             ibput(diskdev, flptr->fl_iba, ibptr);
  576.         }  else  {
  577.             flptr->fl_iba = ibptr->ib_next;
  578.             ibget(diskdev, flptr->fl_iba, ibptr);
  579.         }
  580.     }
  581.     displ = (int)(flptr->fl_pos - ibptr->ib_byte);
  582.     for (flptr->fl_ipnum=0 ; displ>=DBUFSIZ ; displ-=DBUFSIZ)
  583.         flptr->fl_ipnum++;
  584.     flptr->fl_bptr = flptr->fl_buff + displ;
  585.     if ((dba=ibptr->ib_dba[flptr->fl_ipnum]) == DBNULL)  {
  586.         ibptr->ib_dba[flptr->fl_ipnum] = lfsnewd(diskdev,flptr);
  587.         ibput(diskdev, flptr->fl_iba, ibptr);
  588.     }  else
  589.         read(diskdev, flptr->fl_buff, dba);
  590.     flptr->fl_dch = FALSE;
  591. }
  592. /* control.c - control  p. 146 */
  593.  
  594. #include    <conf.h>
  595. #include    <kernel.h>
  596. #include    <io.h>
  597.  
  598. /*-----------------------------------------------------------------------------
  599.  *  control  --  control a device ( e.g., set the mode )
  600.  *-----------------------------------------------------------------------------
  601.  */
  602.  
  603. control(descrp, func, addr, addr2)
  604.     int    descrp, func;
  605.     char    *addr, *addr2;
  606. {
  607.     struct devsw    *devptr;
  608.  
  609.     if (isbaddev(descrp))
  610.         return(SYSERR);
  611.     devptr = &devtab[descrp];
  612.     return((*devptr->dvcntl)(devptr, func, addr, addr2));
  613. }
  614. /* dfdsrch.c - dfdsrch  p. 324 */
  615.  
  616. # include    <conf.h>
  617. # include    <kernel.h>
  618. # include    <disk.h>
  619. # include    <file.h>
  620. # include    <dir.h>
  621.  
  622. /*-----------------------------------------------------------------------------
  623.  *  dfdsrch  --  search disk directory for positioon of given file name
  624.  *-----------------------------------------------------------------------------
  625.  */
  626. struct fdes    *dfdsrch(dsptr, filenam, mbits)
  627.     struct dsblk    *dsptr;
  628.     char    *filenam;
  629.     int    mbits;
  630. {
  631.     struct dir    *dirptr;
  632.     struct fdes    *fdptr;
  633.     int    len;
  634.     int    i;
  635.     int    inum;
  636.  
  637.     if ((len=strlen(filenam))<=0 || len>=FDNLEN)
  638.         return((struct fdes *)SYSERR);
  639.     dirptr = dsdirec(dsptr->dnum);
  640.     for (i=0 ; i<dirptr->d_nfiles ; i++)
  641.         if (strcmp(filenam, dirptr->d_files[i].fdname) == 0)
  642.             if ((mbits&FLNEW) != 0)
  643.                 return((struct fdes *)SYSERR);
  644.             else
  645.                 return(&dirptr->d_files[i]);
  646.     wait(dsptr->ddirsem);
  647.     if ((mbits&FLOLD) || dirptr->d_nfiles>=NFDES)  {
  648.         signal(dsptr->ddirsem);
  649.         return((struct fdes *)SYSERR);
  650.     }
  651.     inum = ibnew(dsptr->dnum, IBNWDIR);
  652.     fdptr = &(dirptr->d_files[dirptr->d_nfiles++]);
  653.     fdptr->fdlen = 0L;
  654.     strcpy(fdptr->fdname, filenam);
  655.     fdptr->fdiba = inum;
  656.     write(dsptr->dnum, dskbcpy(dirptr), DIRBLK);
  657.     signal(dsptr->ddirsem);
  658.     return(fdptr);
  659. }
  660. /* dskenq.c - dskenq  p. 288 */
  661.  
  662. # include    <conf.h>
  663. # include    <kernel.h>
  664. # include    <disk.h>
  665.  
  666. /*-----------------------------------------------------------------------------
  667.  *  dskenq  --  enqueue a disk request and start I/O if disk not busy
  668.  *-----------------------------------------------------------------------------
  669.  */
  670. dskenq(drptr, dsptr)
  671.     struct dreq    *drptr;
  672.     struct dsblk    *dsptr;
  673. {
  674.     struct dreq    *p, *q;        /* q follows p through requests      */
  675.     DBADDR    block;
  676.     int    st;
  677.  
  678.     if ((q=dsptr->dreqlst) == DRNULL)  {
  679.         dsptr->dreqlst = drptr;
  680.         drptr->drnext = DRNULL;
  681.         dskstrt(dsptr);
  682.         return(DONQ);
  683.     }
  684.     block = drptr->drdba;
  685.     for (p=q->drnext ; p != DRNULL ; q=p, p=p->drnext)  {
  686.         if (p->drdba==block && (st=dskqopt(p,q,drptr)!=SYSERR))
  687.             return(st);
  688.         if ((q->drdba <= block && block < p->drdba) ||
  689.             (q->drdba >= block && block > p->drdba))  {
  690.             drptr->drnext = p;
  691.             q->drnext = drptr;
  692.             return(DONQ);
  693.         }
  694.     }
  695.     drptr->drnext = DRNULL;
  696.     q->drnext = drptr;
  697.     return(DONQ);
  698. }
  699. /* dsread.c - dsread  p. 293 */
  700.  
  701. # include    <conf.h>
  702. # include    <kernel.h>
  703. # include    <proc.h>
  704. # include    <disk.h>
  705.  
  706. /*-----------------------------------------------------------------------------
  707.  *  dsread  --  read a block from a disk device
  708.  *-----------------------------------------------------------------------------
  709.  */
  710. dsread(devptr, buff, block)
  711.     struct devsw    *devptr;
  712.     char    *buff;
  713.     DBADDR    block;
  714. {
  715.     struct dreq    *drptr;
  716.     int    stat;
  717.     char    ps;
  718.  
  719.     disable(ps);
  720.     drptr = (struct dreq *) getbuf(dskrbp);
  721.     drptr->drdba  = block;
  722.     drptr->drpid  = currpid;
  723.     drptr->drbuff = buff;
  724.     drptr->drop   = DREAD;
  725.     if ((stat=dskenq(drptr,devptr->dvioblk)) == DONQ)  {
  726.         suspend(currpid);
  727.         stat = drptr->drstat;
  728.     }
  729.     freebuf(drptr);
  730.     restore(ps);
  731.     return(stat);
  732. }
  733. /* freemem.c - freemem  p. 110 */
  734.  
  735. # include    <conf.h>
  736. # include    <kernel.h>
  737. # include    <mem.h>
  738.  
  739. /*-----------------------------------------------------------------------------
  740.  *  freemem  --  free a memory block, returning it to memlist
  741.  *-----------------------------------------------------------------------------
  742.  */
  743. SYSCALL    freemem(block, size)
  744.     struct mblock    *block;
  745.     unsigned    size;
  746. {
  747.     char    ps;
  748.     struct mblock    *p, *q;
  749.     unsigned    top;
  750.  
  751.     if (size==0 || (unsigned)block>(unsigned)maxaddr
  752.             || ((unsigned)block)<((unsigned)&end))
  753.         return(SYSERR);
  754.     size = (unsigned) roundew(size);
  755.     disable(ps);
  756.     for ( p=memlist.mnext,q= &memlist ; p!=NULL && p<block ;
  757.             q=p,p=p->mnext )
  758.         ;
  759.     if ((top=q->mlen+(unsigned)q)>(unsigned)block && q!= &memlist ||
  760.             p!=NULL && (size+(unsigned)block) > (unsigned)p)  {
  761.         restore(ps);
  762.         return(SYSERR);
  763.     }
  764.     if ( q!= &memlist && top == (unsigned)block )
  765.         q->mlen += size;
  766.     else  {
  767.         block->mlen = size;
  768.         block->mnext = p;
  769.         q->mnext = block;
  770.         q = block;
  771.     }
  772.     if ((unsigned)(q->mlen + (unsigned)q) == (unsigned)p)  {
  773.         q->mlen += p->mlen;
  774.         q->mnext = p->mnext;
  775.     }
  776.     restore(ps);
  777.     return(OK);
  778. }
  779. /* getmem.c - getmem  p. 106 */
  780.  
  781. # include    <conf.h>
  782. # include    <kernel.h>
  783. # include    <mem.h>
  784.  
  785. /*-----------------------------------------------------------------------------
  786.  * getmem  --  allocate heap storage, returning lowest integer address
  787.  *-----------------------------------------------------------------------------
  788.  */
  789. int    *getmem(nbytes)
  790.     unsigned    nbytes;
  791. {
  792.     char    ps;
  793.     struct mblock    *p, *q, *leftover;
  794.  
  795.     disable(ps);
  796.     if (nbytes==0 || memlist.mnext==NULL)  {
  797.         restore(ps);
  798.         return((int *)SYSERR);
  799.     }
  800.     nbytes = (unsigned) roundew(nbytes);
  801.     for (q= &memlist,p=memlist.mnext ; p!=NULL ; q=p,p=p->mnext)
  802.         if (p->mlen == nbytes)  {
  803.             q->mnext = p->mnext;
  804.             restore(ps);
  805.             return((int *)p);
  806.         }  else if (p->mlen > nbytes)  {
  807.             leftover = (struct mblock *)((unsigned)p + nbytes);
  808.             q->mnext = leftover;
  809.             leftover->mnext = p->mnext;
  810.             leftover->mlen = p->mlen - nbytes;
  811.             restore(ps);
  812.             return((int *)p);
  813.         }
  814.     restore(ps);
  815.     return((int *)SYSERR);
  816. }
  817. /* ibget.c - ibget  p. 312 */
  818.  
  819. # include    <conf.h>
  820. # include    <kernel.h>
  821. # include    <disk.h>
  822. # include    <file.h>
  823. # include    <dir.h>
  824.  
  825. /*-----------------------------------------------------------------------------
  826.  *  ibget  --  get an iblock from disk given its number
  827.  *-----------------------------------------------------------------------------
  828.  */
  829. ibget(diskdev, inum, loc)
  830.     int    diskdev;
  831.     IBADDR    inum;
  832.     struct iblk    *loc;
  833. {
  834.     char    *from, *to;
  835.     int    i;
  836.     char    *buff;
  837.  
  838.     buff = getbuf(dskdbp);
  839.     read(diskdev, buff, ibtodb(inum));
  840.     from = buff + ibdisp(inum);
  841.     to = (char *)loc;
  842.     for (i=0 ; i<sizeof(struct iblk) ; i++)
  843.         *to++ = *from++;
  844.     freebuf(buff);
  845. }
  846. /* init.c - init  p. 147 */
  847.  
  848. # include    <conf.h>
  849. # include    <kernel.h>
  850. # include    <io.h>
  851.  
  852. /*-----------------------------------------------------------------------------
  853.  *  init  --  initialize a device
  854.  *-----------------------------------------------------------------------------
  855.  */
  856. init(descrp)
  857.     int    descrp;
  858. {
  859.     struct devsw    *devptr;
  860.  
  861.     if (isbaddev(descrp))
  862.         return(SYSERR);
  863.     devptr = &devtab[descrp];
  864.     return ((*devptr->dvinit)(devptr));
  865. }
  866. /* ioerr.c - ioerr  p. 150 */
  867.  
  868. # include    <conf.h>
  869. # include    <kernel.h>
  870.  
  871. /*-----------------------------------------------------------------------------
  872.  *  ioerr  --  return an error (used for "error" entries in devtab)
  873.  *-----------------------------------------------------------------------------
  874.  */
  875. ioerr()
  876. {
  877.     return(SYSERR);
  878. }
  879. /* kprintf.c - kprintf, kputc, savestate, rststate  p. 358 */
  880.  
  881. # include    <conf.h>
  882. # include    <kernel.h>
  883. # include    <io.h>
  884. # include    <slu.h>
  885. # include    <tty.h>
  886.  
  887. /*-----------------------------------------------------------------------------
  888.  *  kprintf  --  kernel printf: formatted, unbuffered output to CONSOLE
  889.  *-----------------------------------------------------------------------------
  890.  */
  891. kprintf(fmt, args)
  892.     char    *fmt;
  893. {
  894.     int    kputc();
  895.  
  896.     savestate();
  897.     _doprnt(fmt, &args, kputc, CONSOLE);
  898.     rststate();
  899.     return(OK);
  900. }
  901.  
  902. /*-----------------------------------------------------------------------------
  903.  *  kputc  --  write a character on the console using polled I/O
  904.  *-----------------------------------------------------------------------------
  905.  */
  906. LOCAL    kputc(device, c)
  907.     int    device;
  908.     register char    c;        /* character to print from _doprnt   */
  909. {
  910.     struct csr    *csrptr;
  911.     int    slowdown;        /* delays output at 9600 baud        */
  912.  
  913.     if (c == 0)
  914.         return;
  915.     if (c == NEWLINE)
  916.         kputc(device, RETURN);
  917.     csrptr = (struct csr *)devtab[device].dvcsr;    /* device address    */
  918.     while ((csrptr->ctstat & SLUREADY) == 0)    /* poll for idle     */
  919.         ;
  920.     csrptr->ctbuf = c;
  921.     for (slowdown=0 ; slowdown<1000 ; slowdown++)
  922.         ;
  923.     while ((csrptr->ctstat & SLUREADY) == 0)    /* poll for idle     */
  924.         ;
  925. }
  926.  
  927. LOCAL int    savecrstat, savectstat;
  928. LOCAL char    saveps;
  929. /*-----------------------------------------------------------------------------
  930.  *  savestate  --  save the console control and status register
  931.  *-----------------------------------------------------------------------------
  932.  */
  933. LOCAL    savestate()
  934. {
  935.     char    ps;
  936.  
  937.     disable(ps);
  938.     saveps = ps;
  939.     savecrstat = (devtab[CONSOLE].dvcsr)->crstat & SLUENABLE;
  940.     (devtab[CONSOLE].dvcsr)->crstat = SLUDISABLE;
  941.     savectstat = (devtab[CONSOLE].dvcsr)->ctstat & SLUENABLE;
  942.     (devtab[CONSOLE].dvcsr)->ctstat = SLUDISABLE;
  943. }
  944.  
  945. /*-----------------------------------------------------------------------------
  946.  *  rststate  --  restore the console output control and status register
  947.  *-----------------------------------------------------------------------------
  948.  */
  949. LOCAL    rststate()
  950. {
  951.     char    ps;
  952.  
  953.     (devtab[CONSOLE].dvcsr)->crstat = savecrstat;
  954.     (devtab[CONSOLE].dvcsr)->ctstat = savectstat;
  955.     ps = saveps;
  956.     restore(ps);
  957. }
  958. /* initialize.c - nulluser, sysinit  p. 192 */
  959.  
  960. # include    <conf.h>
  961. # include    <kernel.h>
  962. # include    <proc.h>
  963. # include    <sem.h>
  964. # include    <mem.h>
  965. # include    <tty.h>
  966. # include    <q.h>
  967. # include    <io.h>
  968. # include    <disk.h>
  969.  
  970. extern int    main();            /* address of user's main prog       */
  971.  
  972. /* Declarations of major kernel variables */
  973.  
  974. struct pentry    proctab[NPROC];        /* process table                     */
  975. int    nextproc;            /* next process slot to use in create*/
  976. struct sentry    semaph[NSEM];        /* semaphore table                   */
  977. int    nextsem;            /* next sem slot to use in screate   */
  978. struct qent    q[NQENT];        /* q table ( see queue.c )           */
  979. int    nextqueue;            /* next slot in q structure to use   */
  980. int    *maxaddr;            /* max memory addr (set by sizemem)  */
  981. # ifdef    NDEVS
  982. struct intmap    intmap[NDEVS];        /* interrupt dispatch table          */
  983. # endif
  984. struct mblock    memlist;        /* list of free memory blocks        */
  985. # ifdef    Ntty
  986. struct tty    tty[Ntty];        /* SLU buffers and mode control      */
  987. # endif
  988.  
  989. /* active system status */
  990.  
  991. int    numproc;            /* number of live user processes     */
  992. int    currpid;            /* id of currently running process   */
  993. int    reboot = 0;            /* non-zero after first boot         */
  994.  
  995. /* real-time clock variables and sleeping process queue pointers */
  996.  
  997. # ifdef    RTCLOCK
  998. int    count6;            /* counts in 60ths of a second 6-0           */
  999. int    defclk;            /* non-zero, then deferring clock count      */
  1000. int    clkdiff;        /* deferred clock ticks                      */
  1001. int    slnempty;        /* FALSE if sleep queue is empty             */
  1002. int    *sltop;            /* address of key part of top entry in the   */
  1003.                 /*  sleep queue if slnempty == TRUE          */
  1004. int    clockq;            /* head of queue of sleeping processes       */
  1005. int    preempt;        /* preemption counter.  Current process is   */
  1006.                 /*  preempted when it reaches zero.          */
  1007.                 /*  set in resched(); counts in ticks        */
  1008. int    clkruns;        /* set TRUE iff clock exists by setclkr      */
  1009. # else
  1010. int    clkruns = FALSE;    /* no clock configured; be sure sleep        */
  1011. # endif                /*  doesn't wait forever                     */
  1012. int    rdyhead, rdytail;    /* head/tail of ready list (q indexes)       */
  1013.  
  1014. /*****************************************************************************
  1015.  ***                                                                       ***
  1016.  ***                           NOTE:                                       ***
  1017.  ***                                                                       ***
  1018.  ***   This is where the system begins after the C environment has been    ***
  1019.  ***   established.  Interrupts are initially DISABLED, and must event-    ***
  1020.  ***   ually be enabled explicitly.  This routine turns itself into the    ***
  1021.  ***   null process after initialization.  Because the null process must   ***
  1022.  ***   always remain ready to run, it cannot execute code that might       ***
  1023.  ***   cause it to be suspended, wait for a semaphore, put to sleep, or    ***
  1024.  ***   exit.  In particular, it must not do I/O unless it uses kprintf     ***
  1025.  ***   for polled output.                                                  ***
  1026.  ***                                                                       ***
  1027.  *****************************************************************************/
  1028.  
  1029. /*-----------------------------------------------------------------------------
  1030.  *  nulluser  -- initialize system and become the null process (id == 0)
  1031.  *-----------------------------------------------------------------------------
  1032.  */
  1033. nulluser()                /* babysit CPU when no one home      */
  1034. {
  1035.     char    ps;
  1036.  
  1037.     kprintf("\n\nXinu Version %s", VERSION);
  1038.     if (reboot++ < 1)
  1039.         kprintf("\n");
  1040.     else
  1041.         kprintf("   (reboot %d)\n", reboot);
  1042.     sysinit();            /* initialize all of Xinu            */
  1043.     kprintf("%u real mem\n", maxaddr+sizeof(int));
  1044.     kprintf("%u avail mem\n",
  1045.         (unsigned)maxaddr-(unsigned)(&end)+(unsigned)sizeof(int));
  1046.     kprintf("clock %sabled\n", clkruns==1 ? "en" : "dis");
  1047.     enable();            /* enable interrupts                 */
  1048.  
  1049.     /* start a process executing the user's main program */
  1050.  
  1051.     resume ( create ( main, INITSTK, INITPRIO, INITNAME, 1, 0 ));
  1052.     while (TRUE)  {            /* run forever without actually      */
  1053.         pause();        /*   executing instructions          */
  1054.     }
  1055. }
  1056.  
  1057. /*-----------------------------------------------------------------------------
  1058.  *  sysint  --  initialize all Xinu data structures and devices
  1059.  *-----------------------------------------------------------------------------
  1060.  */
  1061. LOCAL    sysinit()
  1062. {
  1063.     int    i, j;
  1064.     struct pentry    *pptr;
  1065.     struct sentry    *sptr;
  1066.     struct mblock    *mptr;
  1067.  
  1068.     numproc = 0;            /* initialize system variables       */
  1069.     nextproc = NPROC - 1;
  1070.     nextsem = NSEM - 1;
  1071.     nextqueue = NPROC;        /* q[0..NPROC-1] are processes       */
  1072.     memlist.mnext = mptr =        /* initialize free memory list       */
  1073.         (struct mblock *)roundew(&end);
  1074.     mptr->mnext = (struct mblock *)NULL;
  1075.     mptr->mlen = truncew((unsigned)maxaddr - NULLSTK - (unsigned)&end);
  1076.  
  1077.     for (i=0 ; i<NPROC ; i++)    /* initialize process table          */
  1078.         proctab[i].pstate = PRFREE;
  1079.  
  1080.     pptr = &proctab[NULLPROC];    /* initialize null process entry     */
  1081.     pptr->pstate = PRCURR;
  1082.     for (j=0 ; j<6 ; j++)
  1083.         pptr->pname[j] = "prnull"[j];
  1084.     pptr->plimit = ((int)maxaddr) - NULLSTK;
  1085.     pptr->pbase = maxaddr;
  1086.     pptr->paddr = nulluser;
  1087.     pptr->pargs = 0;
  1088.     currpid = NULLPROC;
  1089.  
  1090.     for (i=0 ; i<NSEM ; i++)  {    /* initialize semaphores             */
  1091.         (sptr = &semaph[i])->sstate = SFREE;
  1092.         sptr->sqtail = 1 + (sptr->sqhead = newqueue());
  1093.     }
  1094.  
  1095.     rdytail = 1 + (rdyhead = newqueue());    /* initialize ready list     */
  1096.  
  1097. # ifdef    MEMMARK
  1098.     _mkinit();            /* initialize memory marking         */
  1099. # endif
  1100. # ifdef    RTCLOCK
  1101.     clkinit();            /* initialize real time clock        */
  1102.     clockq = newqueue();
  1103. # endif
  1104. # ifdef    Ndsk
  1105.     dskdbp = mkpool(DBUFSIZ,NDBUFF);    /* initialize disk buffers   */
  1106.     dskrbp = mkpool(DREQSIZ,NDREQ);
  1107. # endif
  1108.     for (i=0 ; i<NDEVS ; i++)    /* initialize devices                */
  1109.         init(i);
  1110. # ifdef    NNETS
  1111.     netinit();            /* initialize networks               */
  1112. # endif
  1113.     return(OK);
  1114. }
  1115.